/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef NWEB_IMPL_H
#define NWEB_IMPL_H

#include <condition_variable>
#include <list>
#include <memory>
#include <mutex>
#include <vector>
#include "nweb_download_callback.h"
#include "nweb.h"
#include "nweb_input_handler.h"
#include "nweb_inputmethod_handler.h"
#include "nweb_output_handler.h"

namespace OHOS::NWeb {
class NWebImpl : public NWeb {
 public:
  NWebImpl(uint32_t id);
  ~NWebImpl();

  bool Init(const NWebCreateInfo& create_info);
  void OnDestroy() override;

  /* event interface */
  void Resize(uint32_t width, uint32_t height) override;
  void OnTouchPress(int32_t id, double x, double y) override;
  void OnTouchRelease(int32_t id, double x, double y) override;
  void OnTouchMove(int32_t id, double x, double y) override;
  void OnTouchCancel() override;
  void OnNavigateBack() override;
  bool SendKeyEvent(int32_t keyCode, int32_t keyAction) override;
  void SendMouseWheelEvent(double x, double y, double deltaX, double deltaY) override;
  void SendMouseEvent(int x, int y, int button, int action) override;

  // public api
  void Load(const std::string& url) const override;
  bool IsNavigatebackwardAllowed() const override;
  bool IsNavigateForwardAllowed() const override;
  bool CanNavigateBackOrForward(int numSteps) const override;
  void NavigateBack() const override;
  void NavigateForward() const override;
  void NavigateBackOrForward(int step) const override;
  void DeleteNavigateHistory() override;
  void Reload() const override;
  void Zoom(float zoomFactor) const override;
  bool ZoomIn() const override;
  bool ZoomOut() const override;
  void Stop() const override;
  void ExecuteJavaScript(const std::string& code) const override;
  void ExecuteJavaScript(
      const std::string& code,
      std::shared_ptr<NWebValueCallback<std::string>> callback) const override;
  void PutBackgroundColor(int color) const override;
  void InitialScale(float scale) const override;
  void OnPause() const override;
  void OnContinue() const override;
  const std::shared_ptr<NWebPreference> GetPreference() const override;
  void PutDownloadCallback(
      std::shared_ptr<NWebDownloadCallback> downloadListener) override;
  void SetNWebHandler(std::shared_ptr<NWebHandler> handler) override;
  const std::shared_ptr<NWebHandler> GetNWebHandler() const override;
  std::string Title() override;
  uint32_t GetWebId() const override;
  HitTestResult GetHitTestResult() const override;
  int PageLoadProgress() override;
  int ContentHeight() override;
  float Scale() override;
  void Load(std::string& url,
            std::map<std::string, std::string> additionalHttpHeaders) override;
  void LoadWithDataAndBaseUrl(const std::string& baseUrl,
                              const std::string& data,
                              const std::string& mimeType,
                              const std::string& encoding,
                              const std::string& historyUrl) override;
  void LoadWithData(const std::string& data,
                    const std::string& mimeType,
                    const std::string& encoding) override;
  void RegisterArkJSfunction(
      const std::string& object_name,
      const std::vector<std::string>& method_list) override;
  void UnregisterArkJSfunction(
      const std::string& object_name,
      const std::vector<std::string>& method_list) override;
  void SetNWebJavaScriptResultCallBack(
      std::shared_ptr<NWebJavaScriptResultCallBack> callback) override;
  void OnFocus() const override;
  void OnBlur() const override;

  // For NWebEx
  static NWebImpl* FromID(int32_t nweb_id);
  void ReloadOriginalUrl() const;
  static void InitBrowserServiceApi(std::vector<std::string>& browser_args);
  static bool GetBrowserServiceApiEnabled();

 private:
  void ProcessInitArgs(const NWebInitArgs& init_args);
  void InitWebEngineArgs(const NWebInitArgs& init_args);
  bool InitWebEngine(const NWebCreateInfo& create_info);

 private:
  uint32_t nweb_id_ = 0;
  std::shared_ptr<NWebHandler> nweb_handle_ = nullptr;
  std::shared_ptr<NWebOutputHandler> output_handler_ = nullptr;
  std::shared_ptr<NWebInputHandler> input_handler_ = nullptr;
  CefRefPtr<NWebInputMethodHandler> inputmethod_handler_ = nullptr;

  std::shared_ptr<NWebDelegateInterface> nweb_delegate_ = nullptr;
  std::list<std::string> web_engine_args_;
};
}  // namespace OHOS::NWeb

#endif  // NWEB_IMPL_H
